package com.bps.zzant.json;



import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.bps.zzant.model.OrderForm;
import com.bps.zzant.model.OrderGarment;
import com.bps.zzant.model.OrderGarmentItem;
import com.bps.zzant.model.Payment;
import com.bps.zzant.services.OrderService;




@Controller
public class OrderJSON {
	
	   private static final Logger logger = LoggerFactory.getLogger(OrderJSON.class);
	   
		@Autowired
		private OrderService orderService;	   
	   
		public void setOrderService(OrderService orderService) {
			this.orderService = orderService;
		}

	   @InitBinder
	   public void initBinder(WebDataBinder binder) {
	            SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy");
	            dateFormat.setLenient(false);
	            binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
          
	          //  binder.registerCustomEditor(Integer.TYPE, new CustomerDoubleEditor());
	   }
	
/*	   private static class CustomerDoubleEditor extends PropertyEditorSupport{    
		   public void setAsText(String str) { 
		       if(str == null || str.equals("")) 
		           setValue(0); 
		       else 
		        setValue(Double.parseDouble(str)); 
		  } 
		}*/
		
		@RequestMapping(value = "getOrderItemsInSession.json", method = RequestMethod.POST)
		public Map getOrderItemsInSession(HttpServletRequest request, HttpServletResponse response) {
			
			logger.info(" +++++++++in getOrderItemsInSession.json: Order.");
			
			Map<String, Object> map = new HashMap<String, Object>();
			BigDecimal totalPrice = new BigDecimal("0.00");
			
			HttpSession session =  request.getSession();
			List<OrderGarmentItem> orderGarmentItemsList = (List<OrderGarmentItem>) session.getAttribute("ORDER_ITEMS");
			
			if(orderGarmentItemsList!=null){
				for(Iterator i = orderGarmentItemsList.iterator(); i.hasNext();){					
					OrderGarmentItem item = (OrderGarmentItem)i.next();
					totalPrice = item.getSubTotal().add(totalPrice);
					
				}				
				
			}
			map.put("totalPrice", totalPrice);
			
			map.put("rows", orderGarmentItemsList);
			return map;
			 
		}
		
		
		@RequestMapping(value = "clearOrderItems.json", method = RequestMethod.POST)
		public Map clearOrderItemsInSession(HttpServletRequest request, HttpServletResponse response) {
			Map<String, Object> map = new HashMap<String, Object>();
			request.getSession().setAttribute("ORDER_ITEMS", null);
			map.put("success", new Boolean("true"));
			return map; 
		}
		
		
		@RequestMapping(value = "saveOrderItem.json", method = RequestMethod.POST)
		public Map saveOrderItemInSession(@Valid OrderGarmentItem orderGarmentItem, BindingResult errors, HttpServletRequest request){

			Map<String, Object> map = new HashMap<String, Object>();
			HttpSession session =  request.getSession();
			
			
			logger.info(" +++++++++in saveOrderItemInSession.json+++ Item No.:"+orderGarmentItem.getStyleNo());
			logger.info(" +++++++++in saveOrderItemInSession.json+++ description:"+orderGarmentItem.getDesc());
			logger.info(" +++++++++in saveOrderItemInSession.json+++ unitPrice:"+orderGarmentItem.getUnitPrice());
			
						// List productList = productService.getProductByStyleNo("29");
			// logger.info(" ++++ product size: " + productList.size());
			
			if (errors.hasErrors()) {
				logger.info(" +++++++++in saveOrderItemInSession.json+++ has errors " + errors.toString());
				//handle the binding errors
			}else{
				List<OrderGarmentItem> orderGarmentItemsList = (List<OrderGarmentItem>) session.getAttribute("ORDER_ITEMS");
				
				// orderGarmentItem.setLineNo(orderGarmentItemsList==null?1:orderGarmentItemsList.size()+1);
				orderGarmentItem.setSubTotal(orderGarmentItem.getUnitPrice().multiply(new BigDecimal(orderGarmentItem.getQty())));
				
				if(orderGarmentItemsList==null){
					orderGarmentItemsList = new ArrayList<OrderGarmentItem>();
					orderGarmentItemsList.add(orderGarmentItem);
					
				}else{
					orderGarmentItemsList.add(orderGarmentItem);
					
				}				
				
				
				session.setAttribute("ORDER_ITEMS", orderGarmentItemsList);
				map.put("success", new Boolean("true"));

			}
			return map;
		}
		
		@RequestMapping(value = "removeOrderItem.json", method = RequestMethod.POST)
		
		public Map removeOrderItemInSession(@Valid OrderGarmentItem orderGarmentItem, BindingResult errors, HttpServletRequest request) {
			logger.info(" +++++++++in OrderJSON.removeOrderItemInSession. The lineNo is:"+request.getParameter("lineNo"));
			
			int lineNo = Integer.parseInt(request.getParameter("lineNo"));
			
			Map<String, Object> map = new HashMap<String, Object>();
			HttpSession session =  request.getSession();
			List<OrderGarmentItem> orderGarmentItemsList = (List<OrderGarmentItem>) session.getAttribute("ORDER_ITEMS");
			
			orderGarmentItemsList.remove(lineNo);
		
			map.put("success", new Boolean("true"));
			return map; 
		}
		
		@RequestMapping(value = "editOrderItem.json", method = RequestMethod.POST)
		
		public Map editOrderItemInSession(@Valid OrderGarmentItem orderGarmentItem, BindingResult errors, HttpServletRequest request) {
			
			logger.info(" +++++++++in OrderJSON.removeOrderItemInSession. Parameter The lineNo is:"+request.getParameter("lineNo"));
			logger.info(" +++++++++orderItem is:" + orderGarmentItem.getQty() +"|" + orderGarmentItem.getUnitPrice());
			
			Map<String, Object> map = new HashMap<String, Object>();
			HttpSession session =  request.getSession();
			
			orderGarmentItem.setSubTotal(orderGarmentItem.getUnitPrice().multiply(new BigDecimal(orderGarmentItem.getQty())));
			
			List<OrderGarmentItem> orderGarmentItemsList = (List<OrderGarmentItem>) session.getAttribute("ORDER_ITEMS");
						
			int lineNo = Integer.parseInt(request.getParameter("lineNo"));
			orderGarmentItemsList.set(lineNo, orderGarmentItem);

			map.put("success", new Boolean("true"));
			
			return map; 
		}
		
		// this method save the Order into database
		@RequestMapping(value = "saveOrder.json", method = RequestMethod.POST)
		public Map saveOrder(@Valid OrderForm orderForm, BindingResult errors, HttpServletRequest request) {
			
			

			Map<String, Object> map = new HashMap<String, Object>();
			
			HttpSession session =  request.getSession();
			List<OrderGarmentItem> orderGarmentItemsList = (List<OrderGarmentItem>) session.getAttribute("ORDER_ITEMS");
			
			if(orderGarmentItemsList==null || orderGarmentItemsList.size()==0){
				map.put("msg", "You haven't enter any items yet. The order is NOT saved.");
				map.put("success", new Boolean("false"));
			}else{
				
				OrderGarment order = new OrderGarment(orderForm);
				
				logger.info(" +++++++++in OrderJSON.saveOrder 1. "+ order.toString());
				
				order.setOrdersStatus("approved");
				
				for(Iterator i = orderGarmentItemsList.iterator(); i.hasNext();){					
					OrderGarmentItem item = (OrderGarmentItem)i.next();
					item.setOrder(order);
				}
				
				order.setGarmentItems(orderGarmentItemsList);
				
				// set PAYMENT to the OrderGarment domain object
				Payment initDownPayment = new Payment(orderForm);
				initDownPayment.setOrder(order);
				List<Payment> payments = new ArrayList<Payment>();
				payments.add(initDownPayment);
				order.setPayments(payments);
				// end of set PAYMENT
								
				// logger.info(" +++++++++in OrderJSON.saveOrder before save. Item size:" + order.getGarmentItems().size());
				// order.addOrderGarmentItems(orderGarmentItemsList);
				// logger.info(" +++++++++in OrderJSON.saveOrder before save the order id= "+ order.getOrderId());
				
				if(order.getOrderId()>0){					
					// *********** if it is edit order, get the original purchase date, and set it in the order *********
/*					OrderGarment currentOrder = orderService.getOrderById(order.getOrderId());					
					order.setDatePurchased(currentOrder.getDatePurchased());*/
					//*************       end of set original purchase date                                     **********
					logger.info(" +++++++++in OrderJSON.saveOrder Date Purchase:" + order.getDatePurchased());
					order.setLastModified(new Date());
					
					orderService.updateGarmentOrder(order);
				}else{
					order.setDatePurchased(new Date());
					orderService.saveGarmentOrder(order);
				}
				
				logger.info(" +++++++++in OrderJSON.saveOrder after save the order id= "+ order.getOrderId());
				map.put("success", new Boolean("true"));
				map.put("orderId", order.getOrderId());
				map.put("purchaseDate", new SimpleDateFormat("MM/dd/yyyy hh:mm aaa").format(order.getDatePurchased()) );
			}
			
			return map; 
			
		}
		
		
}
